<?php

namespace app\api\service\Activity;

use addons\xyb\XypHelper;
use app\common\model\marketing\Association;
use app\common\model\marketing\AssociationJobs;
use app\common\model\marketing\AssociationProgress;
use app\common\model\marketing\AssociationUsers;
use app\common\model\marketing\MarketingCoupons;
use app\common\model\publics\Huati;


class AssociationService
{

    /**
     * 获取用户参与的社团列表
     *
     * @param int $user_id 用户ID
     * @param int $circle_id 圈子ID
     * @return array 返回社团列表和总数
     */
    public static function getUsersParticipateAssociationLists($user_id, $circle_id)
    {
        // 获取请求参数中的限制数量和页码，默认为10条记录，第1页
        $limit = request()->param('limit', 10);
        $page = request()->param('page', 1);

        // 定义需要查询的字段
        $field = 'id,name,cover,banner,type,describe,guide,start_time,end_time,enroll_start_time,enroll_end_time,
        involved_days,execute_days,activity_method,grant_total,get_limit,grant_method,grant_agent_id,
        grant_users_id,participation_rules,reward_point,status,share_img,share_title,label_id';

        // 初始化查询对象
        $query = Association::field($field)->where('status', '<', 3);

        // 构建复杂的查询条件，包括社团的授权方式和用户、圈子的关系
        $query->where(function ($query) use ($user_id, $circle_id) {
            $query->where('grant_method', 1)->whereOr(function ($q) use ($circle_id, $user_id) {
                $q->whereOr(function ($q) use ($circle_id) {
                    $q->where("grant_method", 2)->whereRaw("FIND_IN_SET('{$circle_id}', grant_agent_id)");
                })->whereOr(function ($q) use ($user_id) {
                    $q->where("grant_method", 3)->whereRaw("FIND_IN_SET('{$user_id}', grant_users_id)");
                });
            });
        });

        // 执行查询并分页
        $association_lists = $query->order('id desc')->paginate($limit, false, ["page" => $page]);

        // 如果没有查询到任何社团，返回空列表和计数0
        if (!$association_lists) {
            return ['list' => [], 'count' => 0];
        }

        // 初始化社团列表数组
        $association_lists_map = [];

        // 遍历查询到的社团，处理每个社团的信息
        foreach ($association_lists as $k => $v) {
            $association_lists_map[$k]['id'] = ($v['id']);
            $association_lists_map[$k]['name'] = ($v['name']);
            $association_lists_map[$k]['cover'] = cdnurl($v['cover']);
            $association_lists_map[$k]['banner'] = cdnurl($v['banner']);
            $association_lists_map[$k]['start_date'] = date('Y-m-d', $v['start_time']);
            $association_lists_map[$k]['end_date'] = date('Y-m-d', $v['end_time']);
            $association_lists_map[$k]['enroll_start_date'] = date('Y-m-d', $v['enroll_start_time']);
            $association_lists_map[$k]['enroll_end_date'] = date('Y-m-d', $v['enroll_end_time']);
            $association_lists_map[$k]['involved_days'] = intval($v['involved_days']);
            $association_lists_map[$k]['execute_days'] = intval($v['execute_days']);
            $association_lists_map[$k]['activity_method'] = intval($v['activity_method']);
            $association_lists_map[$k]['status'] = intval($v['status']);
            $association_lists_map[$k]['enroll_info'] = AssociationUsers::getUsersEnrollStatus($user_id, $v['id']);
            // 根据活动方式计算奖励点数
            if ($v['activity_method'] == 2) {
                $association_lists_map[$k]['reward_point'] = intval($v['reward_point']);
            } else {
                $association['reward_point'] = (int)AssociationJobs::getEveryDayAssociationRewardPoint($v['participation_rules']);
            }
        }
        // 返回处理后的社团列表和总数
        return ['list' => array_values($association_lists_map), 'count' => $association_lists->count()];
    }

    public static function getUsersParticipateAssociationDetails($association_id, $user_id, $circle_id)
    {
        // 定义需要查询的字段
        $field = 'id,name,cover,banner,type,describe,guide,start_time,end_time,enroll_start_time,enroll_end_time,
        involved_days,execute_days,activity_method,grant_total,get_limit,grant_method,grant_agent_id,
        grant_users_id,participation_rules,reward_point,status,slogan';

        // 初始化查询对象，查询状态为1的社团
        $query = Association::field($field)->where('id', $association_id)->where('status', '<', 3);

        // 构建复杂的查询条件，包括社团的授权方式和用户、圈子的关系
        $query->where(function ($query) use ($user_id, $circle_id) {
            $query->where('grant_method', 1)->whereOr(function ($q) use ($circle_id, $user_id) {
                $q->whereOr(function ($q) use ($circle_id) {
                    $q->where("grant_method", 2)->whereRaw("FIND_IN_SET('{$circle_id}', grant_agent_id)");
                })->whereOr(function ($q) use ($user_id) {
                    $q->where("grant_method", 3)->whereRaw("FIND_IN_SET('{$user_id}', grant_users_id)");
                });
            });
        });
        if (!$details = $query->find()) {
            return [];
        }
        $association = [];
        $association['cover'] = cdnurl($details['cover']);
        $association['banner'] = cdnurl($details['banner']);
        $association['describe'] = ($details['describe']);
        $association['guide'] = ($details['guide']);
        $association['slogan'] = ($details['slogan']);
        $association['start_date'] = date('Y-m-d', $details['start_time']);
        $association['end_date'] = date('Y-m-d', $details['end_time']);
        $association['enroll_start_date'] = date('Y-m-d', $details['enroll_start_time']);
        $association['enroll_end_date'] = date('Y-m-d', $details['enroll_end_time']);
        $association['users_enroll_status'] = (time() > $details['enroll_start_time'] && time() < $details['enroll_end_time']);
        $association['involved_days'] = intval($details['involved_days']);
        $association['execute_days'] = intval($details['execute_days']);
        $association['activity_method'] = intval($details['activity_method']);
        $association['status'] = intval($details['status']);
        $association['enroll_info'] = AssociationUsers::getUsersEnrollStatus($user_id, $details['id']);
        $association['reward_point'] = intval($details['reward_point']);
        if ($association['activity_method'] == 2) {
            $association['reward_point'] = (int)AssociationJobs::getEveryDayAssociationRewardPoint($details['participation_rules']);
        }
        $association['participation_rules'] = AssociationJobs::getAssociationJobsItems($association_id, $user_id);
        $association['enroll_users'] = AssociationUsers::getAssociationEnrollUsers($details['id']);
        return $association;
    }

    public static function usersEnrollAssociationTask($association_id, $user_id, $agent_id)
    {
        $field = 'id,start_time,end_time,enroll_start_time,enroll_end_time,grant_total,reward_point,
        get_limit,grant_status,involved_days,execute_days,activity_method,participation_rules';
        $association = Association::where('id', $association_id)
            ->where('start_time', '<=', time())->where('end_time', '>=', time())
            ->where('enroll_start_time', '<=', time())->where('enroll_end_time', '>=', time())
            ->where('grant_method', 1)->where('status', 1)
            ->field($field)
            ->find();
        if (!$association) {
            return ['code' => 0, 'msg' => '活动不存在或已结束'];
        }
        $enroll_total = AssociationUsers::where('association_id', $association_id)->count('id');
        if ($enroll_total >= $association['grant_total']) {
            return ['code' => 0, 'msg' => '活动已满额'];
        }
        $user_enroll_total = AssociationUsers::where('association_id', $association_id)->where('user_id', $user_id)->count('id');
        if ($user_enroll_total >= $association['get_limit']) {
            return ['code' => 0, 'msg' => '您已报名'];
        }
        if ($association['get_limit'] > 1) {
            $enroll_info = AssociationUsers::getUsersEnrollStatus($user_id, $association_id);
            /*任务未完成*/
            if (!$enroll_info['grant_status']) {
                return ['code' => 0, 'msg' => '请先完成任务'];
            }
        }
        $execute_time = (time() + ($association['execute_days'] + 86400));
//        if($execute_time > $association['end_time']){
//            return ['code' => 0, 'msg' => '活动已结束'];
//        }
        $reward_point = intval($association['reward_point']);
        if ($association['activity_method'] == 2) {
            $association['reward_point'] = (int)AssociationJobs::getEveryDayAssociationRewardPoint($association['participation_rules']);
        }
        $deadline = strtotime(date('Y-m-d')) + ($association['involved_days'] + 86400);
        $association_users_data = [
            'association_id' => $association_id,
            'user_id' => $user_id,
            'agent_id' => $agent_id,
            'deadline' => $deadline,
            'execute_days' => $association['execute_days'],
            'complete_days' => 0,
            'activity_method' => $association['activity_method'],
            'obtained_point' => 0,
            'reward_point' => $reward_point,
            'grant_status' => 0,
            'status' => 1,
            'createtime' => time(),
            'updatetime' => time()
        ];
        $res = AssociationUsers::create($association_users_data);
        if (!$res) {
            return ['code' => 0, 'msg' => '报名失败'];
        }
        return ['code' => 1, 'msg' => '报名成功'];
    }

    /**
     * 计算每日关联奖励点
     *
     * 该方法用于计算参与规则中每天关联的所有奖励点总数
     * 它首先将参与规则的JSON字符串转换为数组，然后计算所有奖励点的总和
     *
     * @param int $user_id 用户ID
     * @param array $association 参与规则的JSON字符串，包含每天的奖励点信息
     * @return array 如果转换失败，返回0；否则返回所有奖励点的总和
     */
    public static function formatAssociationRulesItems($user_id, $association)
    {
        if (!$participation_rules = XypHelper::formatJsonStringToArray($association['participation_rules'])) {
            return [];
        }
        $participation_rules_map = [];
        foreach ($participation_rules as $k => $v) {
            $talk_name = '';
            $total_limit = 0;
            $complete_limit = 0;
            if ($v['talk_id']) {
                $talk_name = Huati::where('id', $v['talk_id'])->value('title');
            }
            $image = $video = $text = [
                'stated' => false, 'limit' => 0, 'num' => 0, 'text' => 0, 'talk_id' => 0,
                'talk_name' => '', 'complete_num' => 0, 'complete_stated' => false
            ];
            if (((int)$v['image_stated']) == 1) {
                $image['stated'] = true;
                $image['limit'] = (int)$v['image_limit'];
                $image['num'] = (int)$v['image_num'];
                $image['text'] = (int)$v['image_length'];
                if ($image['talk_id'] = ((int)$v['image_talk_id'])) {
                    $image['talk_name'] = Huati::where('id', $image['image_talk_id'])->value('title');
                }
                $__key = isset($v['__key']) ? $v['__key'] : '';
                $image['complete_num'] = AssociationProgress::getUsersAssociationProgressTotal($user_id, $association['id'], $__key, 'image');
                $image['complete_stated'] = ($image['limit'] == $image['complete_num']);
                $complete_limit = $image['complete_num'];
                $total_limit = $image['limit'];
            }
            if (((int)$v['video_stated']) == 1) {
                $video['stated'] = true;
                $video['limit'] = (int)$v['video_limit'];
                $video['num'] = (int)$v['video_num'];
                $video['text'] = (int)$v['video_length'];
                if ($video['talk_id'] = ((int)$v['video_talk_id'])) {
                    $video['talk_name'] = Huati::where('id', $video['video_talk_id'])->value('title');
                }
                $__key = isset($v['__key']) ? $v['__key'] : '';
                $video['complete_num'] = AssociationProgress::getUsersAssociationProgressTotal($user_id, $association['id'], $__key, 'video');
                $video['complete_stated'] = ($video['limit'] == $video['complete_num']);
                $complete_limit += $video['complete_num'];
                $total_limit += $video['limit'];
            }
            if (((int)$v['text_stated']) == 1) {
                $text['stated'] = true;
                $text['limit'] = (int)$v['text_limit'];
                $text['text'] = (int)$v['text_length'];
                if ($text['talk_id'] = ((int)$v['text_talk_id'])) {
                    $text['talk_name'] = Huati::where('id', $text['text_talk_id'])->value('title');
                }
                $__key = isset($v['__key']) ? $v['__key'] : '';
                $text['complete_num'] = AssociationProgress::getUsersAssociationProgressTotal($user_id, $association['id'], $__key, 'text');
                $text['complete_stated'] = ($text['limit'] == $text['complete_num']);
                $complete_limit += $text['complete_num'];
                $total_limit += $text['limit'];
            }
            $participation_rules_map[$k]['total_limit'] = $total_limit;
            $participation_rules_map[$k]['talk_id'] = intval($v['talk_id']);
            $participation_rules_map[$k]['talk_name'] = $talk_name;
            $participation_rules_map[$k]['reward_point'] = (int)$v['reward_point'];
            $participation_rules_map[$k]['complete_limit'] = $complete_limit;
            $participation_rules_map[$k]['complete_stated'] = ($complete_limit == $total_limit);
            $participation_rules_map[$k]['image'] = $image;
            $participation_rules_map[$k]['video'] = $video;
            $participation_rules_map[$k]['text'] = $text;
            $participation_rules_map[$k]['name'] = $v['name'];
        }
        return $participation_rules_map;
    }

    /*获取日常任务*/
    public static function getUsersParticipateDailyAssociationLists( $user_id, $circle_id ) {
        // 获取请求参数中的限制数量和页码，默认为10条记录，第1页
        $limit = request()->param('limit', 10);
        $page = request()->param('page', 1);

        /*->where('start_time', '<', time())->where('end_time', '>', time())*/
        /* 获取正常的活动信息 */
        $query = Association::where('status', 1)->where('activity_method', 2);

//        // 构建复杂的查询条件，包括社团的授权方式和用户、圈子的关系
//        $query->where(function ($query) use ($user_id, $circle_id) {
//            $query->where('grant_method', 1)->whereOr(function ($q) use ( $circle_id, $user_id ) {
//                $q->whereOr(function ($q) use ($circle_id) {
//                    $q->where("grant_method", 2)->whereRaw("FIND_IN_SET('{$circle_id}', grant_agent_id)");
//                })->whereOr(function ($q) use ($user_id) {
//                    $q->where("grant_method", 3)->whereRaw("FIND_IN_SET('{$user_id}', grant_users_id)");
//                });
//            });
//        });
        if(!$association_ids = $query->order('id desc')->column('id')){
            return ['list' => [], 'count' => 0];
        }

        /*根据活动获取任务列表*/
        if(!$jobs_lists = AssociationJobs::getDaysAssociationJobsByAssociationIds( $association_ids, $user_id, $page, $limit)){
            return ['list' => [], 'count' => 0];
        }


        $participation_rules_map = [];
        foreach ($jobs_lists as $list){
            $participation_rules_map[] = AssociationJobs::formatDailyAssociationRulesItems($list);

        }
        if(!$participation_rules_map){
            return ['list' => [], 'count' => $jobs_lists->total()];
        }

        return ['list' => array_values($participation_rules_map), 'count' => $jobs_lists->total()];
    }

    public static function getUsersParticipateDailyAssociationRecommendLists( $user_id, $circle_id ){
        // 获取请求参数中的限制数量和页码，默认为10条记录，第1页
        $limit = request()->param('limit', 10);
        $assemble = request()->param('assemble', 2);

        /* 获取正常的活动信息 */
        $query = Association::where('status', 1)->where('activity_method', 2)
            ->where('start_time', '<', time())->where('end_time', '>', time());

//        // 构建复杂的查询条件，包括社团的授权方式和用户、圈子的关系
        $query->where(function ($query) use ($user_id, $circle_id) {
            $query->where('grant_method', 1)->whereOr(function ($q) use ( $circle_id, $user_id ) {
                $q->whereOr(function ($q) use ($circle_id) {
                    $q->where("grant_method", 2)->whereRaw("FIND_IN_SET('{$circle_id}', grant_agent_id)");
                })->whereOr(function ($q) use ($user_id) {
                    $q->where("grant_method", 3)->whereRaw("FIND_IN_SET('{$user_id}', grant_users_id)");
                });
            });
        });
        if(!$association_ids = $query->order('id desc')->column('id')){
            return [];
        }
        /*根据活动获取任务列表*/
        if(!$jobs_lists = AssociationJobs::getDaysAssociationJobsRecommendByAssociationIds( $association_ids, $user_id, $limit)){
            return [];
        }
        $participation_rules_map = [];
        foreach ($jobs_lists as $list){
            $participation_rules_map[] = AssociationJobs::formatDailyAssociationRulesItems($list);
        }
        $reward_point = array_sum(array_column($participation_rules_map, 'reward_point'));
        if(!$participation_rules_map){
            return [];
        }
        $lists = array_chunk($participation_rules_map, $assemble, false);
        return ['lists' => $lists, 'point' => floatval($reward_point)];
    }

    public static function getUsersParticipateDailyLists( $user_id, $circle_id ){
        /*获取用户的参与记录*/

        /*状态：1：待审核；2：审核通过；3：审核拒绝*/
        $status = request()->param('status', 2);

        /*奖励发放状态 奖励发放状态:0=未发放,1=已发放*/
        $reward_stated = request()->param('reward_stated', 1);
        /*奖励领取状态 领取状态:1=未领取,2=已领取*/
        $receive_stated = request()->param('receive_stated', 0);
        $field = 'yx_association_progress.id,association_jobs.reward_method,association_jobs.reward_point,
        association_jobs.youth_point,reward_coupons_id,association_jobs.name,association_jobs.talk_id,
        yx_association_progress.receive_stated,yx_association_progress.status as examine_stated';
        $query = AssociationProgress::field($field)
            ->join('association_jobs', 'yx_association_progress.jobs_id = association_jobs.id')
           // ->where('yx_association_progress.user_id', $user_id)
            ->where('association_jobs.activity_method', 2)
            ->where('association_jobs.reward_method', 'in', [3, 4, 5])
            ->where('yx_association_progress.reward_stated', $reward_stated);
        if($receive_stated == 1){
            $query->where('yx_association_progress.receive_stated', 0);
        }elseif($receive_stated == 2){
            $query->where('yx_association_progress.receive_stated', 1);
        }
        if($status == 1){
            $query->where('yx_association_progress.status', 1);
        }
        elseif($status == 2){
            $query->where('yx_association_progress.status', 'in', [2, 4]);
        }elseif($status == 3){
            $query->where('yx_association_progress.status', 'in',[3, 5]);
        }
        $lists = $query->paginate();

        if(!$lists->items()){
            return $lists;
        }

        foreach ($lists->items() as $key => $value){
            $value['talk_name'] = Huati::where($value['talk_id'])->value('title');
            if($value['reward_coupons_id']){
                $value['reward_coupons'] = MarketingCoupons::getAssociationCouponsArray($value['reward_coupons_id']);
            }
            $examine_stated = 0;
            if(in_array($value['examine_stated'], [2, 4])){
                $examine_stated = 2;
            }elseif(in_array($value['examine_stated'], [3, 5])){
                $examine_stated = 3;
            }else {
                $examine_stated = 1;
            }
            $value['examine_stated'] = $examine_stated;
        }
        return $lists;
    }
}